/*
 * @Description: socket对象
 * @Author: xinqiao lxq1990.0716@qq.com
 * @Date: 2025-04-17
 * @LastEditors: xinqiao lxq1990.0716@qq.com
 * @LastEditTime: 2025-04-28
 */

import { closeHeartbeat, openHeartbeat, openRegistry } from './connect'

class SSCWebSocket {
  /** socket对象 */
  socket?: WebSocket
  /** 请求链接 */
  url: string
  /** 用户id */
  userId: string
  /** 连接状态 */
  connectState: number
  /** 监听：连接打开 */
  onopen: Function
  /** 监听：消息接收 */
  onmessage: Function
  /** 监听：连接关闭 */
  onclose: Function
  /** 监听：出错 */
  onerror: Function

  constructor() {
    this.socket = undefined
    this.url = ''
    this.userId = ''
    this.connectState = WebSocket.CLOSED
    this.onopen = () => {}
    this.onmessage = () => {}
    this.onclose = () => {}
    this.onerror = () => {}
  }

  /**
   * 初始化配置
   * @param url 请求链接
   * @param onOpen 打开连接回调
   * @param onMessage 接收消息回调
   * @param onClose 关闭连接回调
   * @param onError 错误回调
   */
  init({ url, userId, onOpen = () => {}, onMessage = () => {}, onClose = () => {}, onError = () => {} }) {
    this.url = url
    this.userId = userId
    this.onopen = onOpen
    this.onmessage = onMessage
    this.onclose = onClose
    this.onerror = onError
  }

  /**
   * 打开连接
   */
  connect() {
    console.log('connect-url: ', this.url)
    this.socket = new WebSocket(this.url)
    this.connectState = WebSocket.CONNECTING
    this.bindEvent()
  }

  /**
   * 关闭连接
   */
  close() {
    this.socket?.close()
  }

  /**
   * 绑定事件（打开连接、关闭连接、接收消息、错误异常）
   */
  bindEvent() {
    const socket = this.socket as WebSocket

    socket.onopen = (event) => {
      console.log('--this.socket.onopen--')
      this.connectState = WebSocket.OPEN
      this.onopen(event)
      openRegistry(socket, this.connectState, this.userId)
      openHeartbeat(socket, this.connectState, this.userId)
    }

    socket.onmessage = (event) => {
      console.log('--this.socket.onmessage--')
      this.onmessage(event)
    }

    socket.onclose = (event) => {
      console.log('--this.socket.onclose--')
      this.connectState = WebSocket.CLOSED
      this.onclose(event)
      closeHeartbeat()
    }

    socket.onerror = (event) => {
      console.log('--this.socket.onerror--')
      this.onerror(event)
    }
  }

  /**
   * 发送消息
   * @param msg 消息内容
   */
  send(msg: string) {
    if (this.connectState !== WebSocket.OPEN) {
      console.log('send error: WebSocket is not open')
      return
    }
    this.socket?.send(msg)
  }
}

export default new SSCWebSocket()
